/*
 * Context.cpp
 *
 *  Created on: Aug 5, 2009
 *      Author: ramesh
 */

#include "Context.h"
#include "Class.h"

using namespace SymphonyAST;


Context::Context() {
	offset = 0;
}


Variable* Context::getVariable(const string& name) {
	map<string, Variable*>::iterator var = varTable.find(name);

	if (var == varTable.end())
		return parent->getVariable(name);
	else
		return var->second;
}

void Context::addVariable(string name, Variable* variable) {
	if (varTable.find(name) != varTable.end()) {
		throw "Duplicated declaration of " + name;
	}

	//not yet reserved
	if (variable->address == -1) {
		variable->address = getAbsOffset();
		//sometimes we can add a var of which we don't know the type yet
		offset += variable->getSize() == 0 ? 8 : variable->getSize();
	}
	varTable[name] = variable;
}


void Context::addChild(Context* node) {
	node->parent = this;
	children.push_back(node);
}
Context* Context::removeChild(int i) {
	return *(children.erase(children.begin()+i));
}

vector<Context*> Context::getChildren() {
	return children;
}
void Context::clearChildren() {
	children.clear();
}

Context* Context::getChild(int i) {
	return children[i];
}

void Context::setChild(int i, Context* child) {
	children[i] = child;
}
void Context::setChildren(vector<Context*>& children) {
	this->children = children;
}


StackPointer Context::getOffset() {
	return offset;
}

void Context::setOffset(StackPointer offset) {
	this->offset = offset;
}

StackPointer Context::getAbsOffset() {
	if (getId() != "method")
		return getOffset() + ((Context*)parent)->getAbsOffset();
	else
		return getOffset();
}

void Context::incOffset(StackPointer inc) {
	offset += inc;
}

void Context::decOffset(StackPointer dec) {
	offset += dec;
}
